/** \file
* Declarations for the generic XML source class.
* This file is part of Chorus, available at
* http://code.google.com/p/chorus-twitter/ . This file and all associated files
* and derivative works are bound by the terms of the LGPL 3.0 license,
* available at http://www.gnu.org/licenses/lgpl-3.0-standalone.html .
* \par Subversion URL:
* \$URL: http://chorus-twitter.googlecode.com/svn/branches/cpp/src/xml/XmlSource.hpp $
* \version \$Rev: 153 $
* \date    \$Date: 2010-04-06 07:43:42 +0000 (Tue, 06 Apr 2010) $
*/

#pragma once

#include <string>
#include <libxml/parser.h>

#include "xml/XmlTree.hpp"


/// The abstract XML source class. Cannot be instantiated directly.
class XmlSource
{
protected:
	/// The constructor.
	/// \param treeInit The XmlTree to which we send parse events.
	/// \param pathInit The path to the file.
	XmlSource(XmlTree *treeInit, const std::string &pathInit);
public:
	/// The destructor.
	virtual ~XmlSource();

public:
	/// Fetch the data from the source.
	/// \return True for success.
	bool fetch();

protected:
	/// Internal function to do the work of getting the data.
	/// \return True for success.
	virtual bool perform() = 0;

	/// perform() calls this with chunks of XML data so that we can parse it.
	/// \param buffer The data buffer.
	/// \param size   The size of the buffer.
	/// \return True for success.
	bool writeData(const char *buffer, size_t size);

private:
	/// The XML/SAX handler for element start (static callback).
	/// \param ctx   The this-pointer.
	/// \param name  The name of the element.
	/// \param attrs The list of attributes, alternating between name and value
	///              and ending with a null.
	static void saxStartElement(void *ctx, const xmlChar *name,
		const xmlChar **attrs);

	/// The XML/SAX handler for element end (static callback).
	/// \param ctx   The this-pointer.
	/// \param name  The name of the element.
	static void saxEndElement(void *ctx, const xmlChar *name);

	/// The XML/SAX handler for extra-tag characters (static callback).
	/// \param ctx The this-pointer.
	/// \param ch  The data.
	/// \param len The data length.
	static void saxCharacters(void *ctx, const xmlChar *ch, int len);

	/// The XML/SAX handler for warning and error messages (static callback).
	/// \param ctx The this-pointer.
	/// \param msg The printf-like format string.
	/// \param ... The printf-like vargs.
	static void saxMessage(void *ctx, const char *msg, ...);

protected:
	/// The XML parser context.
	xmlParserCtxt *context;
	/// The path to the file or web location.
	const std::string path;

private:
	/// The XML/SAX handler structure.
	const static xmlSAXHandler sax;

protected:
	/// The tree to which we send XML parse events.
	XmlTree *const tree;
};
